特别是在定义事务代理的时候,你可能会需要处理很多相似的代理。使用父子bean的定义,可以让代理的定义变得清晰简洁。
首先定义一个父的代理bean作为模板:

<bean id="txProxyTemplate" abstract="true"
        class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
    <property name="transactionManager" ref="transactionManager"/>
    <property name="transactionAttributes">
        <props>
            <prop key="*">PROPAGATION_REQUIRED</prop>
        </props>
    </property>
</bean>

它不会实例化自身,用于被补充完整。其余要被创建的Bean都是子bean,它将代理的目标作为内部bean封装,这样目标将永远不会由自己使用。

<bean id="myService" parent="txProxyTemplate">
    <property name="target">
        <bean class="org.springframework.samples.MyServiceImpl">
        </bean>
    </property>
</bean>

当然可以重写父模板中的属性,就像这个例子中事务的传播设置:

<bean id="mySpecialService" parent="txProxyTemplate">
    <property name="target">
        <bean class="org.springframework.samples.MySpecialServiceImpl">
        </bean>
    </property>
    <property name="transactionAttributes">
        <props>
            <prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
            <prop key="find*">PROPAGATION_REQUIRED,readOnly</prop>
            <prop key="load*">PROPAGATION_REQUIRED,readOnly</prop>
            <prop key="store*">PROPAGATION_REQUIRED</prop>
        </props>
    </property>
</bean>

注意上面的例子中,我们将父bean通过abstract属性定义成抽象的,正如之前所说的,这样这个bean实际将不被实例化。Application contexts(非简单的bean factory)默认会预实例化全部的单例对象。因此(至少对于单例的bean)很重要的一点是,当你有一个只用作模板的bean定义,且这个定义指定了一个类,你要确保设置abstract属性为true,否则application context实际上回尝试预初始化它。